package net.ncraft.mc.ezframework.core.gui.einventory;

import lombok.Getter;
import lombok.Setter;
import net.ncraft.mc.ezframework.core.SpigotEzFrameworkCore;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

import java.util.ArrayList;
import java.util.List;

public class EInventory implements Listener {
    @Getter
    @Setter
    private String title;
    @Getter
    @Setter
    private Player player;
    @Getter
    @Setter
    private int size;
    @Getter
    private final List<InvElement> elements = new ArrayList<>();
    @Getter
    @Setter
    private Inventory bukkitInventory;
    @Getter
    private int nowPage = 1;
    @Getter
    @Setter
    InvAction onClose;
    @Getter
    @Setter
    InvAction onOpen;



    public EInventory(String title, int size) {
        this(title, size, (i, p) -> {
        }, (i, p) -> {
        });
    }

    public EInventory(String title, int size, InvAction onOpen, InvAction onClose) {
        this.title = title;
        this.size = size;
        this.onOpen = onOpen;
        this.onClose = onClose;
    }

    public void addElement(InvElement element) {
        elements.add(element);
        element.setInventory(this);
    }

    public void addElements(InvElement... elements) {
        for (InvElement element : elements) {
            addElement(element);
        }
    }

    public void addElementGroup(InvElementGroup group) {
        for (InvElement element : group.getElements()) {
            addElement(element);
        }
    }

    public void open(Player player) {
        this.player = player;
        init();
        player.openInventory(bukkitInventory);
    }

    public void updateTitle(String newTitle) {
        player.getOpenInventory().setTitle(newTitle);
    }


    public void close() {
        player.closeInventory();
    }

    public void nextPage() {
        nowPage++;
        flush();
    }

    public void previousPage() {
        if (nowPage == 1) {
            return;
        }
        nowPage--;
        flush();
    }

    private void init() {
        SpigotEzFrameworkCore.getPlugin().getServer().getPluginManager().registerEvents(this, SpigotEzFrameworkCore.getPlugin());
        elements.sort((o1, o2) -> {
            if (o1.getSlot() > o2.getSlot()) {
                return 1;
            } else if (o1.getSlot() < o2.getSlot()) {
                return -1;
            }
            return o1.getPriority() - o2.getPriority();
        });
        bukkitInventory = Bukkit.createInventory(player, size, title);
        flush();
    }

    //核心逻辑
    public void flush() {
        ItemStack[] items = new ItemStack[size];
        for (InvElement e : elements) {

            if (e.getEleType()==InvElementType.FIXED) {
                items[e.getSlot()] = e.getItemStack();
            }

            if (e.getEleType() == InvElementType.VAR) {
                int page = e.getSlot() / size + 1;
                int slot = e.getSlot() % size;

                if (items[slot] == null) {
                    if (page == nowPage) {
                        items[slot] = e.getItemStack();
                    }
                }
            }
        }
        bukkitInventory.setContents(items);
    }



    @EventHandler
    public void onClick(InventoryClickEvent event) {

        if (event.getClickedInventory() == bukkitInventory) {
            for (InvElement element : elements) {
                if (element.getSlot() == event.getSlot()) {
                    element.onClick();
                    event.setCancelled(true);
                }
            }
        }
    }

    @EventHandler
    public void onClose(InventoryCloseEvent event) {
        if (event.getInventory() != bukkitInventory) {
            return;
        }
        if (onClose != null) {
            onClose.run(this, player);
            event.getHandlers().unregister(this);
        }else {
            event.getHandlers().unregister(this);
        }

    }

    @EventHandler
    public void onOpen(InventoryCloseEvent event) {
        if (event.getInventory() != bukkitInventory) {
            return;
        }
        if (onOpen != null) {
            onOpen.run(this, player);
        }

    }

}
